package com.googlecode.stemwijzer.client.presenter;

import java.util.List;

import net.customware.gwt.presenter.client.EventBus;
import net.customware.gwt.presenter.client.place.Place;
import net.customware.gwt.presenter.client.widget.WidgetDisplay;

import com.allen_sauer.gwt.log.client.Log;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.inject.Inject;
import com.googlecode.stemwijzer.client.StemwijzerServiceAsync;
import com.googlecode.stemwijzer.client.event.AllQuestionsAnsweredEvent;
import com.googlecode.stemwijzer.client.event.ExceptionEvent;
import com.googlecode.stemwijzer.client.event.NotificationEvent;
import com.googlecode.stemwijzer.shared.data.QuestionnaireData;
import com.googlecode.stemwijzer.shared.model.IsAnswer;
import com.googlecode.stemwijzer.shared.model.IsQuestion;

public class AnswerQuestionPresenter extends AbstractPresenter<AnswerQuestionPresenter.Display> {

	public interface Display extends WidgetDisplay {
		void showQuestion(final String questionText);

		IsAnswer getAnswer();

		void clearAnswer();

		HasClickHandlers getPrevious();

		HasClickHandlers getNext();
	}

	public static final Place PLACE = new Place("AnswerQuestionPresenter");

	private StemwijzerServiceAsync service;

	private List<IsQuestion> questions = QuestionnaireData.getAvailableQuestions();

	private int progress = 0;

	@Inject
	public AnswerQuestionPresenter(Display display, EventBus eventBus, StemwijzerServiceAsync service) {
		super(display, eventBus);

		this.service = service;

		bind();
	}

	@Override
	public Place getPlace() {
		return PLACE;
	}

	@Override
	protected void onBind() {
		display.getPrevious().addClickHandler(new PreviousClickHandler());
		display.getNext().addClickHandler(new NextClickHandler());

		initialize();
	}

	@Override
	public void revealDisplay() {
	}

	@Override
	public void refreshDisplay() {
		Log.debug("Refreshing display");

		if (progress >= 0 && progress < questions.size()) {
			IsQuestion q = questions.get(progress);

			display.clearAnswer();
			display.showQuestion("\"" + q.getText() + "\"");
		} else if (progress == questions.size()) {
			eventBus.fireEvent(new AllQuestionsAnsweredEvent());
			eventBus.fireEvent(new NotificationEvent("Alle vragen zijn beantwoord"));

			unbind();
		} else {
			eventBus.fireEvent(new ExceptionEvent("Deze vraag bestaat niet"));
		}
	}

	public void initialize() {
		progress = 0;
		display.clearAnswer();

		refreshDisplay();
	}

	private final class PreviousClickHandler implements ClickHandler {

		@Override
		public void onClick(ClickEvent event) {
			if (progress > 0) {
				progress--;
			}
			refreshDisplay();
		}
	}

	private final class NextClickHandler implements ClickHandler {

		@Override
		public void onClick(ClickEvent event) {
			IsQuestion q = questions.get(progress);
			IsAnswer a = display.getAnswer();

			if (a == null) {
				eventBus.fireEvent(new ExceptionEvent("Geen antwoord gekozen, probeer opnieuw"));
			} else {
				display.startProcessing();

				service.sendAnswer(q, a, new AnswerSentCallback());
			}
		}
	}

	private final class AnswerSentCallback implements AsyncCallback<Boolean> {

		@Override
		public void onSuccess(Boolean IsAnswerSent) {
			display.stopProcessing();

			if (IsAnswerSent) {
				eventBus.fireEvent(new NotificationEvent("Antwoord opgeslagen"));
				progress++;
				refreshDisplay();
			} else {
				eventBus.fireEvent(new ExceptionEvent("Antwoord niet is niet correct opgeslagen"));
			}
		}

		@Override
		public void onFailure(Throwable t) {
			display.stopProcessing();
			eventBus.fireEvent(new ExceptionEvent("FOUT", t));
		}
	}
}
